package com.example.easycharge.controller;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.easycharge.annotation.PassToken;
import com.example.easycharge.entity.Customer;
import com.example.easycharge.error.UsedUserNameError;
import com.example.easycharge.error.UserNotFoundError;
import com.example.easycharge.notRepEntity.LoginData;
import com.example.easycharge.notRepEntity.SignUpData;
import com.example.easycharge.repository.CustomerRepository;
import com.example.easycharge.service.BillService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

/*
    登陆与注册的接口

 */
@Tag(name = "用户的登陆与注册")
@Slf4j
@RestController
@RequestMapping("api")
public class ApiController {
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private BCryptPasswordEncoder encoder;
    @Autowired
    private BillService billService;

    @Operation(description = "登录接口，采用token验证")
    @PassToken
    @PostMapping("/login")
    public Object login(@RequestBody LoginData user) throws UserNotFoundError {
        JSONObject returnJson = new JSONObject();
        String userName = user.getUserName();
        Customer dataBaseUser = customerRepository.findCustomerByUserName(userName);
        if (dataBaseUser == null) {
            throw new UserNotFoundError();
        } else {
            if (!encoder.matches(user.getUserPassword(), dataBaseUser.getUserPassword())) {
                returnJson.put("message", "密码错误");
            } else {
                //在这里生成token
                String token = JWT.create()
                        .withClaim("userName", userName)
                        .withClaim("userId", dataBaseUser.getUserId())
                        .withClaim("roleId", dataBaseUser.getUserRoleId())
                        .withClaim("expireTime", new Date().getTime())
                        .sign(Algorithm.HMAC256(dataBaseUser.getUserPassword()));

                DecodedJWT decodedJWT = JWT.decode(token);
                returnJson.put("token", token);
                returnJson.put("message", "登陆成功");
                dataBaseUser.setUserPassword("*");//不返回用户密码
                returnJson.put("user", dataBaseUser);
            }
        }
        return returnJson;
    }

    @Operation(description = "注册接口")
    @PassToken
    @PostMapping("/signup")
    public JSONObject signUp(@RequestBody SignUpData signUpData) throws UsedUserNameError {
        JSONObject jsonObject = new JSONObject();
        Customer user = new Customer(signUpData);
        if (customerRepository.countCustomerByUserName(user.getUserName()) != 0) {
            throw new UsedUserNameError();
        }
        user.setUserPassword(encoder.encode(user.getUserPassword()));

        customerRepository.save(user);

        jsonObject.put("message", "注册成功");
        user.setUserPassword("*");
        jsonObject.put("userDetail", user);
        return jsonObject;
    }

    @Operation(description = "查询是否存在相同用户名")
    @PassToken
    @GetMapping("count/{userName}")
    public JSONObject countUserName(@PathVariable("userName") String userName) {
        JSONObject jsonObject = new JSONObject();
        int count = customerRepository.countCustomerByUserName(userName);
        jsonObject.put("count", count);
        return jsonObject;
    }

    @Operation(description = "初始化服务器")
    @PassToken
    @PutMapping("/init")
    public JSONObject init() {
        JSONObject result = new JSONObject();
        result.put("message", billService.initBill());
        return result;
    }

    @Operation(description = "查看当前时间和电价")
    @PassToken
    @GetMapping("/time")
    public String getTime() {
        return billService.getNowTime();
    }
}
